// 导出所有中间件
export * from './error';
export * from './auth';
export * from './logger';
export * from './rateLimit';
export * from './swagger';

import { Context, Next } from 'koa';
import { ResponseUtil } from '@/utils/response';

/**
 * 响应时间中间件
 */
export const responseTime = async (ctx: Context, next: Next): Promise<void> => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  ctx.set('X-Response-Time', `${ms}ms`);
};

/**
 * 请求 ID 中间件
 */
export const requestId = async (ctx: Context, next: Next): Promise<void> => {
  const reqId = ctx.headers['x-request-id'] as string || 
                Math.random().toString(36).substring(2, 15);
  
  ctx.state.requestId = reqId;
  ctx.set('X-Request-ID', reqId);
  
  await next();
};

/**
 * 健康检查中间件
 */
export const healthCheck = async (ctx: Context, next: Next): Promise<void> => {
  if (ctx.path === '/health' || ctx.path === '/ping') {
    ctx.status = 200;
    ctx.body = ResponseUtil.success({
      status: 'ok',
      timestamp: new Date().toISOString(),
      uptime: process.uptime(),
      memory: process.memoryUsage(),
      version: process.version,
    }, '服务正常运行');
    return;
  }
  
  await next();
};

/**
 * CORS 预检请求处理中间件
 */
export const corsPreflightHandler = async (ctx: Context, next: Next): Promise<void> => {
  if (ctx.method === 'OPTIONS') {
    ctx.status = 204;
    return;
  }
  
  await next();
};

/**
 * 安全头中间件
 */
export const securityHeaders = async (ctx: Context, next: Next): Promise<void> => {
  // 设置安全相关的响应头
  ctx.set('X-Content-Type-Options', 'nosniff');
  ctx.set('X-Frame-Options', 'DENY');
  ctx.set('X-XSS-Protection', '1; mode=block');
  ctx.set('Referrer-Policy', 'strict-origin-when-cross-origin');
  
  // 移除服务器信息
  ctx.remove('X-Powered-By');
  
  await next();
};

/**
 * 压缩响应中间件（简单实现）
 */
export const compression = async (ctx: Context, next: Next): Promise<void> => {
  await next();
  
  // 设置压缩相关头部
  const acceptEncoding = ctx.headers['accept-encoding'];
  if (acceptEncoding && acceptEncoding.includes('gzip')) {
    ctx.vary('Accept-Encoding');
  }
};